package com.pdf;

import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 文件转换工具类，支持将不同类型的文件转换为指定格式（pdf或html）。
 *
 * //进入目录
 * cd C:\Program Files (x86)\OpenOffice 4\program
 * //启动OpenOffice服务
 * soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard
 * //查看是否启动成功
 * netstat -ano|findstr "8100"
 * //终止进程
 * taskkill /F /PID 2032
 */
@Slf4j
public class FileConversionUtil {

    /**
     * 被转换文件类型的枚举，用于表示支持的文件类型。
     */
    public enum FileType {
        DOC, DOCX, XLS, XLSX, PPT, PPTX;

        /**
         * 获取小写文件类型列表
         *
         * @return 小写文件类型列表
         */
        public static List<String> getLowerCaseFileTypes() {
            return Arrays.stream(values())
                    .map(FileType::name)
                    .map(String::toLowerCase)
                    .collect(Collectors.toList());
        }
    }

    /**
     * 转换文件类型的枚举，用于表示支持的文件类型。
     */
    public enum ConvertFileType {
        PDF, HTML;

        /**
         * 获取小写文件类型列表
         *
         * @return 小写文件类型列表
         */
        public static List<String> getLowerCaseFileTypes() {
            return Arrays.stream(values())
                    .map(ConvertFileType::name)
                    .map(String::toLowerCase)
                    .collect(Collectors.toList());
        }
    }

    /**
     * 执行文件格式转换。
     *
     * @param originalFilePath  原始文件路径
     * @param convertedFilePath 转换后文件保存路径
     * @return 转换是否成功
     */
    public static boolean convertToPdf(String originalFilePath, String convertedFilePath) {
        // 获取原始文件扩展名
        String originalExt = FilenameUtils.getExtension(originalFilePath);
        List<String> lowerCaseFileTypes = FileType.getLowerCaseFileTypes();
        // 检查原始文件类型是否支持
        if (!lowerCaseFileTypes.contains(originalExt)) {
            throw new RuntimeException("错误的转换类型：只允许格式为：" + StringUtils.join(lowerCaseFileTypes, ",") + " 进行转换");
        }

        // 获取目标文件扩展名
        String convertExt = FilenameUtils.getExtension(convertedFilePath);
        List<String> convertFileTypes = ConvertFileType.getLowerCaseFileTypes();

        // 检查目标文件类型是否支持
        if (!convertFileTypes.contains(convertExt)) {
            throw new RuntimeException("错误的转换类型：只允许转换为：" + StringUtils.join(convertFileTypes, ","));
        }

        try {
            // 连接 OpenOffice 服务。需提前开启 OpenOffice 服务，否则会报错。
            OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
            try {
                connection.connect();
            } catch (Exception e) {
                throw new RuntimeException("连接 OpenOffice 服务失败，请检查是否启动 OpenOffice 服务,错误信息：" + e.getMessage());
            }

            // 转化原始文件转化为 pdf 或 html
            log.info("开始转换......");
            long startTime = System.currentTimeMillis();

            DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
            converter.convert(new File(originalFilePath), new File(convertedFilePath));

            long endTime = System.currentTimeMillis();
            log.info("转换完成,耗时: {} 毫秒", endTime - startTime);

            connection.disconnect();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }


    public static void main(String[] args) {
        String file ="D:\\cutcutcut\\aa.doc";

        String pdfFile = "D:\\cutcutcut\\aa.pdf";
        FileConversionUtil.convertToPdf(file, pdfFile);
    }
}

